package com.dnd.monitor.strategy;

import com.dnd.monitor.common.config.DynamicContextHolder;
import com.dnd.monitor.common.constant.Constant;
import com.dnd.monitor.common.utils.DocNumUtil;
import com.dnd.monitor.entity.DocumentNumberCalc;
import com.dnd.monitor.mapper.MonitorMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * @author 安贺
 * @createTime 2022年08月10日 14:03:00
 *      公共更新方法
 *
 *      1.为什么另起线程去做更新，因为无法在aop切面之后去再次切换数据源，就是手动去切换
 *      在contextHolder（本地线程中）中会再次被覆盖，网上有其他方法，切换为栈存储数据源信息，但是支持10个数据源
 *      ，没有采用
 *      2.通过cas确保单个单个地区执行。
 */
@Component
@Slf4j
public class CommonMonitor {

    @Autowired
    private MonitorMapper monitorMapper;


    AtomicReference<String> stringAtomicReference = new AtomicReference<>();


    public void monitorExecute(List<DocumentNumberCalc> calcList) {
        if (stringAtomicReference.compareAndSet(null, calcList.get(0).getAreaName())) {
            System.out.println("当前匹配的数据源为：'"+DynamicContextHolder.peek()+"'");
            String areaName = calcList.get(0).getAreaName();
            //获取地区名称
            log.info("开始检测'{}'文书号数据...", areaName);
            List<DocumentNumberCalc> collect = calcList.stream().map(documentNumberCalc -> {
                String dataType = documentNumberCalc.getDataType();
                //先初始化好wshNew1，wshNew2
                String wshNew1 = documentNumberCalc.getWshNew1();
                String wshNew2 = documentNumberCalc.getWshNew2();
                //获取转换为百分号的文书号
                String wshNew1Per = DocNumUtil.symbol2Percent(wshNew1);
                String s1 = DocNumUtil.str2OnlyWordAndNum(wshNew1);
                //如果文书号1和文书号2不一样，两次查询，否则查询一次
                List<String> allDocNum = new ArrayList<>();
                if (!documentNumberCalc.getWshNew1().equals(documentNumberCalc.getWshNew2())) {
                    //获取转换为百分号的文书号
                    String wshNew2Per = DocNumUtil.symbol2Percent(wshNew2);
                    String s2 = DocNumUtil.str2OnlyWordAndNum(wshNew2);
                    List<String> docNums2 = monitorMapper.getDiffAreaDocNumWith1(wshNew1Per, dataType);
                    List<String> docNums1 = monitorMapper.getDiffAreaDocNumWith2(wshNew2Per, dataType);
                    allDocNum.addAll(docNums1);
                    allDocNum.addAll(docNums2);
                    boolean flag = false;
                    for (String s : allDocNum) {
                        //如果文书号1或者2等于查询处理的数据，或都去掉符号相等
                        String selectStr = DocNumUtil.str2OnlyWordAndNum(s);
                        if (wshNew1.equals(s) || wshNew2.equals(s) ||
                                s1.equals(selectStr) || s2.equals(selectStr) ||
                                selectStr.contains(s1) || selectStr.contains(s2)) {
                            flag = true;
                            break;
                        }
                    }
                    //如果true,证明存在，设置为已上报，否则瞒报
                    if (flag) {
                        documentNumberCalc.setCheckResult(Constant.REPORTED);
                    } else {
                        documentNumberCalc.setCheckResult(Constant.UN_REPORT);
                    }
                } else {
                    allDocNum = monitorMapper.getDiffAreaDocNumWith1(wshNew1Per, dataType);
                    boolean flag = false;
                    for (String s : allDocNum) {
                        //如果文书号1或者2等于查询处理的数据，或都去掉符号相等
                        String selectStr = DocNumUtil.str2OnlyWordAndNum(s);
                        if (wshNew1.equals(s) || s1.equals(selectStr) || selectStr.contains(s1)) {
                            flag = true;
                            break;
                        }
                    }
                    if (flag) {
                        documentNumberCalc.setCheckResult(Constant.REPORTED);
                    } else {
                        documentNumberCalc.setCheckResult(Constant.UN_REPORT);
                    }
                }
                return documentNumberCalc;
            }).collect(Collectors.toList());
            log.info("'{}'数据检测对比完成...", areaName);
            CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {
                if (stringAtomicReference.get().equals(areaName)) {
                    try {
                        monitorMapper.batchUpdateCheckResult(collect,areaName);
                        log.info("'{}'数据更新完成...", areaName);
                    } catch (Exception e) {
                        log.info("'{}'数据更新失败...", areaName);
                    }
                }
                return Constant.FINISHED;
            });
            String s = completableFuture.join();
            if (Constant.FINISHED.equals(s)) {
                stringAtomicReference.compareAndSet(calcList.get(0).getAreaName(), null);
            }
        }
    }
}
